/**
 *  @file enemyShip.cpp
 *
 *  @date 16-nov-2009
 *  @author Ives van der Flaas
 */

#include <cassert>
#include <typeinfo>
#include "enemyShip.h"
#include "randomNumberGenerator.h"
#include "linearController.h"
#include "sinusoidalController.h"
#include "circularBoundingBox.h"

namespace si
{

EnemyShip::EnemyShip(si::Vector2 startPosition, ShipDescr descriptor):
	Ship(descriptor.startHealth, descriptor.size),
	fAvgTimeToShooting(descriptor.fireFreq),
	fProjectileType(descriptor.projType)
{

	// Build controller...
	if(typeid(SinusoidalControllerDescr) == typeid(*descriptor.controller))
	{
		std::tr1::shared_ptr<SinusoidalControllerDescr> sinCon
							= std::tr1::dynamic_pointer_cast<SinusoidalControllerDescr>(descriptor.controller);

		fController = std::tr1::shared_ptr<si::Controller>(
				new si::SinusoidalController(
						si::Vector2(startPosition.getX()-fVirtualSize.getX()/2, startPosition.getY()),
						sinCon->vSpeed,
						sinCon->sweepWidth,
						fVirtualSize));
	}
	else if(typeid(LinearControllerDescr) == typeid(*descriptor.controller))
	{
		std::tr1::shared_ptr<LinearControllerDescr> linCon
									= std::tr1::dynamic_pointer_cast<LinearControllerDescr>(descriptor.controller);

		// startPosition is center startposition!!
		fController = std::tr1::shared_ptr<si::Controller>(
				new si::LinearController(
					si::Vector2(startPosition.getX()-fVirtualSize.getX()/2, startPosition.getY()),
					linCon->speed,
					fVirtualSize));
	}
	else
	{
		assert(false);
	}

	fBoundingBox = std::tr1::shared_ptr<si::BoundingBox>(
			new CircularBoundingBox(startPosition-fVirtualSize/2, fVirtualSize.getX()/2));

}

EnemyShip::~EnemyShip()
{
	// TODO Auto-generated destructor stub
}

void EnemyShip::update(double time)
{
	Ship::update(time);

	int topRange = static_cast<int>(fAvgTimeToShooting/time);
	if(topRange < 0)
		topRange = 0;

	// Only fire when we're alive & on screen (when off screen bullets disappear!)
	if((fHealth > 0) &&
			(RandomNumberGenerator::get().randomInRange(0, topRange) == 0) &&
			(fController->getPosition().getX()-fVirtualSize.getX() < 3.0))
			fire();

	fBoundingBox->setCenter(
					si::Vector2(
							fController->getPosition().getX()+fVirtualSize.getX()/2,
							fController->getPosition().getY()-fVirtualSize.getY()/2));

}
}
